package x.trident.core.micro.gateway.modular.validate;

import cn.hutool.core.util.StrUtil;
import x.trident.core.auth.api.SessionManagerApi;
import x.trident.core.auth.api.exception.AuthException;
import x.trident.core.auth.api.exception.enums.AuthExceptionEnum;
import x.trident.core.auth.api.pojo.login.LoginUser;
import x.trident.core.jwt.api.JwtApi;
import x.trident.core.micro.api.constants.MicroConstants;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static x.trident.core.auth.api.exception.enums.AuthExceptionEnum.AUTH_EXPIRED_ERROR;

/**
 * token校验
 *
 * @author Seven
 * @date 2021/5/13 21:30
 */
@Service
public class TokenService {

    @Resource
    private JwtApi jwtApi;

    @Resource
    private SessionManagerApi sessionManagerApi;

    /**
     * 获取请求token，获取不到返回空
     *
     * @author Seven
     * @date 2021/5/12 22:31
     */
    public String getToken(ServerHttpRequest request) {

        // 1. 优先从param参数中获取token
        String parameterToken = request.getQueryParams().getFirst(MicroConstants.TOKEN_PARAM_NAME);

        // 不为空则直接返回param的token
        if (StrUtil.isNotBlank(parameterToken)) {
            return parameterToken;
        }

        // 2. 从header中获取token
        String authToken = request.getHeaders().getFirst(MicroConstants.AUTH_HEADER_NAME);
        if (StrUtil.isNotBlank(authToken)) {
            return authToken;
        }

        return null;
    }

    /**
     * 校验token是否正确
     *
     * @author Seven
     * @date 2021/5/13 21:31
     */
    public void validateToken(String token) {

        // 校验jwt token的正确性
        boolean tokenFlag = jwtApi.validateToken(token);

        // 如果token错误正确
        if (!tokenFlag) {
            throw new AuthException(AuthExceptionEnum.TOKEN_PARSE_ERROR);
        }

        // 校验token在session缓存中是否存在
        LoginUser session = sessionManagerApi.getSession(token);
        if (session == null) {
            throw new AuthException(AUTH_EXPIRED_ERROR);
        }
    }

}
